#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "math.h"

#include "./st.h"
#include "./config.h"

/* lots o ambition to develop this project, for example, one could make use of pthread to generate a thread for each of the instruments,
the args could represent filenames to files consisting of rhythms as well as the frequency and/or type of wave
rhythms would be defined as 10001000 for example, where 0 translates to skip an iteration
each of the threads would be generating output to be | into aplay, to generate music
surely it works!
if threading doesnt work out, work out how to add mutliple frequencies together? */

void die() {
    printf("\
usage: stunes <file> [<file> ...]\n\
  - up to 8 files can be specified\n");
    exit(1);
}

/* enums */

/* data types */
typedef struct {
    char type;
    char* load;
} line;

/* function declarations */
int read_rhythm(FILE*, int);
line parse_line(FILE*);

/* variables */
/* collection of error messages */
static char* errmesgs[2] = {
    "all ok",
    "invalid syntax (check config.h for available symbols)",
};

/* function implementations */

/* reads a line into a string, if the line is structured validly */
/*   skips the first character and all whitespaces up to the actual payload */
/*   before \n */
/* returns a line struct with the probed character signifying the type of */
/*   line, as well as the additional contents of the line */
/* returns -1 as the line type if the line type was not recognized */
line parse_line(FILE* in)
{
    char c;
    char ret = -1;

    long read;
    // TODO: fix parsing bug when comment immediately follows empty line
    c = probe_line(in, symbols, &read);
    if (c == -1) {
        line l1 = { -1, "" };
        return l1;
    }

    /* set recognized line type */
    if (in_array(symbols, c)) ret = c;

    /* skip whitespaces and comments */
    if (ret == '\n' || ret == '#') {
        /* set pointer in file to correct pos */
        skip(in, '\n');
        /* return 'ignore' line type */
        line l2 = { '-', "" };
        return l2;
    }

    /* line type was recognized, now scan for size of the line load */
    /* this doesn't check for whitespaces (which are later ignored), so the */
    /*   char buffer will usually be a little bigger in size than the actual load */
    int chars = seek_char(in, '\n');
    char load[chars];
    char* loadp = load;
    if (ret != -1) {
        /* consume type character, since we already knwo the type */
        c = getc(in);
        while (!feof(in) && c != '\n') {
            c = getc(in);
            if (c == ' ') continue;
            *loadp = c;
            loadp++;
        }
        *loadp = '\0';
    }

    /* actual data */
    line l3 = { ret, load };
    return l3;
}

/* parses the rhythm of a rhythm file */
/* on failure returns the error code that references an 'errmesgs' error, */
/*   otherwise 0 */
int read_rhythm(FILE* in, int channel)
{
    char* seq;
    char* t;
    int freq;

    // TODO: actually use the data and save structs
    line l;
    for (int i = 0; i < 5; i++) {
        l = parse_line(in);
        if (l.type == -1) return 1;
        if (l.type == '-') continue;
        printf("LOAD %s FIN\n", l.load);
        printf("TYPE %c FIN\n", l.type);
        printf("i %i\n", i);
    }

    return 0;

    /* old, replaced by function pointers soon */
    enum wav type;
    if (strcmp(t, "wcon") == 0) {
        type = wcon;
    } else if (strcmp(t, "wsin") == 0) {
        type = wsin;
    } else if (strcmp(t, "wcos") == 0) {
        type = wcos;
    } else if (strcmp(t, "wtan") == 0) {
        type = wtan;
    } else {
        type = wcon;
    }

    rhythm ch = { seq, type, freq };
    channels[channel] = ch;

    printf("parsed channel %i\n", channel);
    return 0;
}

int main(int argc, char **argv) {
    /* ensure user is not retarded */
    if (argc < 2 || argc > 9)
        die();

    int ret;
    /* loop argument files */
    for (int ch = 0; ch < argc-1; ch++) {
        int arg = ch + 1;
        FILE* f = fopen(argv[arg], "r");

        /* fopen returned NULL */
        if (f == NULL) {
            fprintf(stderr, "error while opening file %s for reading, ignoring...\n", argv[arg]);
            continue;
        }

        /* read rhythm of file */
        if ((ret = read_rhythm(f, ch))) {
            /* in case of error, print 'errmesgs' element specified by ret */
            fprintf(stderr, "error while reading file %s: %s\nignoring file %s...\n", argv[arg], errmesgs[ret], argv[arg]);
            continue;
        }
    }

    return 0;
}
